package indi.cloud.common.elasticsearch.impl;

import indi.cloud.common.elasticsearch.EsDataService;
import indi.cloud.common.elasticsearch.EsQueryParse;
import indi.cloud.common.elasticsearch.core.EsBaseReq;
import indi.cloud.common.elasticsearch.core.EsPageable;
import indi.cloud.common.elasticsearch.core.EsResult;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.SearchScrollHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.annotation.Annotation;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 *
 */
@Service
public class EsDataServiceImpl implements EsDataService {
    //    @Resource
//    private RestClient restClient;
    @Resource
    private ElasticsearchRestTemplate elasticsearchTemplate;


    @Override
    public <T> T save(T t) {
        return elasticsearchTemplate.save(t);
    }

    @Override
    public <T> boolean batchSave(List<T> tList) {
        elasticsearchTemplate.save(tList);
        return true;
    }

    @Override
    public <T> boolean update(T t) {
        return true;
    }

    @Override
    public <T> boolean batchUpdate(List<T> tList) {
        return true;
    }

    @Override
    public <T> boolean delete(Class<T> clazz, String id) {
        Annotation annotation = AnnotationUtils.getAnnotation(clazz, Document.class);
        Document document = (Document) annotation;
        IndexCoordinates index = IndexCoordinates.of(document.indexName());
        elasticsearchTemplate.delete(id, index);
        return true;
    }

    @Override
    public <T> boolean batchDelete(Class<T> clazz, List<String> idList) {
        Annotation annotation = AnnotationUtils.getAnnotation(clazz, Document.class);
        Document document = (Document) annotation;
        IndexCoordinates index = IndexCoordinates.of(document.indexName());
        idList.forEach(id -> elasticsearchTemplate.delete(id, index));
        return true;
    }

    @Override
    public <T> T findById(Class<T> clazz, String id) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.matchQuery("_id", id));
        SearchHit<T> searchHit = elasticsearchTemplate.searchOne(queryBuilder.build(), clazz);
        return searchHit == null ? null : searchHit.getContent();
    }

    @Override
    public <T> T findOne(Class<T> clazz, Query query) {
        SearchHit<T> searchHit = elasticsearchTemplate.searchOne(query, clazz);
        return searchHit == null ? null : searchHit.getContent();
    }

    @Override
    public <T> T findOne(Class<T> clazz, EsBaseReq esBaseReq) {
        Query query = EsQueryParse.convert2Query(esBaseReq);
        SearchHit<T> searchHit = elasticsearchTemplate.searchOne(query, clazz);
        return searchHit != null ? searchHit.getContent() : null;
    }

    @Override
    public <T> EsResult<List<T>> findAll(Class<T> clazz) {
        SearchHits<T> searchHits = elasticsearchTemplate.search(Query.findAll(), clazz);
        List<T> data = searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
        return EsResult.of(data, searchHits.getTotalHits());
    }

    @Override
    public <T> EsResult<List<T>> findAll(Class<T> clazz, EsPageable pageable) {
        Query query = new StringQuery(QueryBuilders.boolQuery().toString());
        query.setPageable(EsPageable.getQueryPageable(pageable));
        query.addSort(EsPageable.getQuerySort(pageable));

        SearchHits<T> search = elasticsearchTemplate.search(query, clazz);
        List<T> data = search.get().map(SearchHit::getContent).collect(Collectors.toList());
        long recordCount = search.getTotalHits();
        return EsResult.of(data, recordCount);
    }

    @Override
    public <T> EsResult<List<T>> search(Class<T> clazz, Query query) {
        SearchHits<T> searchHit = elasticsearchTemplate.search(query, clazz);
        List<T> data = searchHit.get().map(SearchHit::getContent).collect(Collectors.toList());
        long recordCount = searchHit.getTotalHits();
        return EsResult.of(data, recordCount);
    }

    @Override
    public <T> EsResult<List<T>> searchScroll(Class<T> clazz, Query query,String indexName) {
        long scrollTimeInMillis = 60 * 1000;
        List<T> data = new ArrayList<>();
        SearchScrollHits<T> searchHit = elasticsearchTemplate.searchScrollStart(scrollTimeInMillis, query, clazz, IndexCoordinates.of(indexName));
        String scrollId = searchHit.getScrollId();
        data = searchHit.get().map(SearchHit::getContent).collect(Collectors.toList());
        //滚动查询
        while (searchHit.hasSearchHits()) {
            searchHit = elasticsearchTemplate.searchScrollContinue(scrollId, scrollTimeInMillis, clazz, IndexCoordinates.of(indexName));
            List<T> temp = searchHit.get().map(SearchHit::getContent).collect(Collectors.toList());
            data.addAll(temp);
            scrollId = searchHit.getScrollId();
        }
        long recordCount = data.size();
        return EsResult.of(data, recordCount);
    }

    @Override
    public <T> EsResult<List<T>> search(Class<T> t, EsBaseReq request) {
        //组装查询
        Query query = EsQueryParse.convert2Query(request);
        //组装分页
        query.setPageable(EsPageable.getQueryPageable(request));
        //组装排序
        query.addSort(EsPageable.getQuerySort(request));
        System.out.println(query);
        SearchHits<T> searchHits = elasticsearchTemplate.search(query, t);
        List<T> data = searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
        long recordCount = searchHits.getTotalHits();
        return EsResult.of(data, recordCount);
    }

    @Override
    public <T> EsResult<List<T>> dslSearch(Class<T> t, String dsl) {
        if (StringUtils.isBlank(dsl)) {
            throw new RuntimeException("sql语句不存在");
        }
        StringQuery stringQuery = new StringQuery(dsl);

        SearchHits<T> searchHits = elasticsearchTemplate.search(stringQuery, t);
        List<T> data = searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
        long recordCount = searchHits.getTotalHits();
        return EsResult.of(data, recordCount);
    }

    @Override
    public <T> EsResult<List<T>> search(Class<T> t, JSONObject request) {
        // 主查询体
        BoolQueryBuilder mainBuilder = QueryBuilders.boolQuery();
        // or查询分类
        BoolQueryBuilder exersiceBoolQuery = QueryBuilders.boolQuery();

        // 企业类型
        String entType = request.getString("ent_type");
        if (!Strings.isNullOrEmpty(entType)) {
            // 精确查询
            List<String> ent = Splitter.on(",").splitToList(entType);
            for (String record : ent) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("ent_type.keyword", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // 企业性质
        String nature = request.getString("nature");
        if (!Strings.isNullOrEmpty(nature)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> natureList = Splitter.on(",").splitToList(nature);
            for (String record : natureList) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("nature.keyword", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }


        // 行业
        String industry = request.getString("industry");
        if (!Strings.isNullOrEmpty(industry)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> industries = Splitter.on(",").splitToList(industry);
            for (String record : industries) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("ccx_industry_code.keyword", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // 区域
        String regions = request.getString("regions");
        if (!Strings.isNullOrEmpty(regions)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> regionList = Splitter.on(",").splitToList(regions);
            for (String record : regionList) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("province_code.keyword", record));
                exersiceBoolQuery.should(QueryBuilders.termQuery("city_code.keyword", record));
                exersiceBoolQuery.should(QueryBuilders.termQuery("county_code.keyword", record));
                exersiceBoolQuery.should(QueryBuilders.termQuery("p_functional_code.keyword", record));
                exersiceBoolQuery.should(QueryBuilders.termQuery("functional_code.keyword", record));
                exersiceBoolQuery.should(QueryBuilders.termQuery("platform_region_code.keyword", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // QE评级
        String qe_eval = request.getString("qe_eval");
        if (!Strings.isNullOrEmpty(qe_eval)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> qeList = Splitter.on(",").splitToList(qe_eval);
            for (String record : qeList) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("qe_eval.keyword", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // 外部评级
        String external_eval = request.getString("external_eval");
        if (!Strings.isNullOrEmpty(external_eval)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> eeList = Splitter.on(",").splitToList(external_eval);
            for (String record : eeList) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("external_eval.keyword", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // 外部评级展望
        String external_eval_info = request.getString("external_eval_info");
        if (!Strings.isNullOrEmpty(external_eval_info)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> eeiList = Splitter.on(",").splitToList(external_eval_info);
            for (String record : eeiList) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("external_eval_info.keyword", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // 是否上市
        String listed = request.getString("listed");
        if (!Strings.isNullOrEmpty(listed)) {
            mainBuilder.must(QueryBuilders.termQuery("listed.keyword", listed));
        }

        // 财报年份
        String year = request.getString("year");
        if (!Strings.isNullOrEmpty(year)) {
            mainBuilder.must(QueryBuilders.termQuery("year", year));
        }

        // 总资产
        String ZB_0101_begin = request.getString("ZB_0101_begin");
        String ZB_0101_end = request.getString("ZB_0101_end");
        if (!Strings.isNullOrEmpty(ZB_0101_begin) && !Strings.isNullOrEmpty(ZB_0101_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0101").gte(ZB_0101_begin).lte(ZB_0101_end));
        } else if (!Strings.isNullOrEmpty(ZB_0101_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0101").gte(ZB_0101_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0101_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0101").lte(ZB_0101_end));
        }

        // 净资产
        String ZB_0105_begin = request.getString("ZB_0105_begin");
        String ZB_0105_end = request.getString("ZB_0105_end");
        if (!Strings.isNullOrEmpty(ZB_0105_begin) && !Strings.isNullOrEmpty(ZB_0105_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0105").gte(ZB_0105_begin).lte(ZB_0105_end));
        } else if (!Strings.isNullOrEmpty(ZB_0105_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0105").gte(ZB_0105_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0105_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0105").lte(ZB_0105_end));
        }

        // 营业收入
        String ZB_0302_begin = request.getString("ZB_0302_begin");
        String ZB_0302_end = request.getString("ZB_0302_end");
        if (!Strings.isNullOrEmpty(ZB_0302_begin) && !Strings.isNullOrEmpty(ZB_0302_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0302").gte(ZB_0302_begin).lte(ZB_0302_end));
        } else if (!Strings.isNullOrEmpty(ZB_0302_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0302").gte(ZB_0302_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0302_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0302").lte(ZB_0302_end));
        }

        // 净利润
        String ZB_0303_begin = request.getString("ZB_0303_begin");
        String ZB_0303_end = request.getString("ZB_0303_end");
        if (!Strings.isNullOrEmpty(ZB_0303_begin) && !Strings.isNullOrEmpty(ZB_0303_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0303").gte(ZB_0303_begin).lte(ZB_0303_end));
        } else if (!Strings.isNullOrEmpty(ZB_0303_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0303").gte(ZB_0303_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0303_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0303").lte(ZB_0303_end));
        }

        // 有息债务 产业
        String ZB_0108_begin = request.getString("ZB_0108_begin");
        String ZB_0108_end = request.getString("ZB_0108_end");
        if (!Strings.isNullOrEmpty(ZB_0108_begin) && !Strings.isNullOrEmpty(ZB_0108_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0108").gte(ZB_0108_begin).lte(ZB_0108_end));
        } else if (!Strings.isNullOrEmpty(ZB_0108_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0108").gte(ZB_0108_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0108_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0108").lte(ZB_0108_end));
        }

        // 有息债务 城投
        String ZB_0126_begin = request.getString("ZB_0126_begin");
        String ZB_0126_end = request.getString("ZB_0126_end");
        if (!Strings.isNullOrEmpty(ZB_0126_begin) && !Strings.isNullOrEmpty(ZB_0126_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0126").gte(ZB_0126_begin).lte(ZB_0126_end));
        } else if (!Strings.isNullOrEmpty(ZB_0126_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0126").gte(ZB_0126_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0126_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0126").lte(ZB_0126_end));
        }

        // 短债占比 产业
        String ZB_0116_begin = request.getString("ZB_0116_begin");
        String ZB_0116_end = request.getString("ZB_0116_end");
        if (!Strings.isNullOrEmpty(ZB_0116_begin) && !Strings.isNullOrEmpty(ZB_0116_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0116").gte(ZB_0116_begin).lte(ZB_0116_end));
        } else if (!Strings.isNullOrEmpty(ZB_0116_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0116").gte(ZB_0116_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0116_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0116").lte(ZB_0116_end));
        }

        // 短债占比 城投
        String ZB_0130_begin = request.getString("ZB_0130_begin");
        String ZB_0130_end = request.getString("ZB_0130_end");
        if (!Strings.isNullOrEmpty(ZB_0130_begin) && !Strings.isNullOrEmpty(ZB_0130_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0130").gte(ZB_0130_begin).lte(ZB_0130_end));
        } else if (!Strings.isNullOrEmpty(ZB_0130_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0130").gte(ZB_0130_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0130_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0130").lte(ZB_0130_end));
        }

        // 资产负债率
        String ZB_0110_begin = request.getString("ZB_0110_begin");
        String ZB_0110_end = request.getString("ZB_0110_end");
        if (!Strings.isNullOrEmpty(ZB_0110_begin) && !Strings.isNullOrEmpty(ZB_0110_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0110").gte(new BigDecimal(ZB_0110_begin)).lte(new BigDecimal(ZB_0110_end)));
        } else if (!Strings.isNullOrEmpty(ZB_0110_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0110").gte(new BigDecimal(ZB_0110_begin)));
        } else if (!Strings.isNullOrEmpty(ZB_0110_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0110").lte(new BigDecimal(ZB_0110_end)));
        }

        // 有息负债率
        String ZB_0117_begin = request.getString("ZB_0117_begin");
        String ZB_0117_end = request.getString("ZB_0117_end");
        if (!Strings.isNullOrEmpty(ZB_0117_begin) && !Strings.isNullOrEmpty(ZB_0117_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0117").gte(ZB_0117_begin).lte(ZB_0117_end));
        } else if (!Strings.isNullOrEmpty(ZB_0117_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0117").gte(ZB_0117_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0117_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0117").lte(ZB_0117_end));
        }

        // 毛利率
        String ZB_0307_begin = request.getString("ZB_0307_begin");
        String ZB_0307_end = request.getString("ZB_0307_end");
        if (!Strings.isNullOrEmpty(ZB_0307_begin) && !Strings.isNullOrEmpty(ZB_0307_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0307").gte(ZB_0307_begin).lte(ZB_0307_end));
        } else if (!Strings.isNullOrEmpty(ZB_0307_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0307").gte(ZB_0307_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0307_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0307").lte(ZB_0307_end));
        }

        // 总资产收益率
        String ZB_0311_begin = request.getString("ZB_0311_begin");
        String ZB_0311_end = request.getString("ZB_0311_end");
        if (!Strings.isNullOrEmpty(ZB_0311_begin) && !Strings.isNullOrEmpty(ZB_0311_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0311").gte(ZB_0311_begin).lte(ZB_0311_end));
        } else if (!Strings.isNullOrEmpty(ZB_0311_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0311").gte(ZB_0311_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0311_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0311").lte(ZB_0311_end));
        }

        // 净资产收益率
        String ZB_0313_begin = request.getString("ZB_0313_begin");
        String ZB_0313_end = request.getString("ZB_0313_end");
        if (!Strings.isNullOrEmpty(ZB_0313_begin) && !Strings.isNullOrEmpty(ZB_0313_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0313").gte(ZB_0313_begin).lte(ZB_0313_end));
        } else if (!Strings.isNullOrEmpty(ZB_0313_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0313").gte(ZB_0313_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0313_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0313").lte(ZB_0313_end));
        }

        // 经营活动净现金流
        String ZB_0401_begin = request.getString("ZB_0401_begin");
        String ZB_0401_end = request.getString("ZB_0401_end");
        if (!Strings.isNullOrEmpty(ZB_0401_begin) && !Strings.isNullOrEmpty(ZB_0401_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0401").gte(ZB_0401_begin).lte(ZB_0401_end));
        } else if (!Strings.isNullOrEmpty(ZB_0401_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0401").gte(ZB_0401_begin));
        } else if (!Strings.isNullOrEmpty(ZB_0401_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("ZB_0401").lte(ZB_0401_end));
        }

        // 债券违余额
        String debSum_begin = request.getString("debSum_begin");
        String debSum_end = request.getString("debSum_end");
        if (!Strings.isNullOrEmpty(debSum_begin) && !Strings.isNullOrEmpty(debSum_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("debSum").gte(debSum_begin).lte(debSum_end));
        } else if (!Strings.isNullOrEmpty(debSum_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("debSum").gte(debSum_begin));
        } else if (!Strings.isNullOrEmpty(debSum_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("debSum").lte(debSum_end));
        }

        // 主体利差
        String all_pb_begin = request.getString("all_pb_begin");
        String all_pb_end = request.getString("all_pb_end");
        if (!Strings.isNullOrEmpty(all_pb_begin) && !Strings.isNullOrEmpty(all_pb_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("all_pb").gte(all_pb_begin).lte(all_pb_end));
        } else if (!Strings.isNullOrEmpty(all_pb_begin)) {
            mainBuilder.must(QueryBuilders.rangeQuery("all_pb").gte(all_pb_begin));
        } else if (!Strings.isNullOrEmpty(debSum_end)) {
            mainBuilder.must(QueryBuilders.rangeQuery("all_pb").lte(all_pb_end));
        }

        String regionYear = request.getString("regionYear");

        if (!Strings.isNullOrEmpty(regionYear)) {
            // GDP
            String QY010101_begin = request.getString("QY010101_begin");
            String QY010101_end = request.getString("QY010101_end");
            if (!Strings.isNullOrEmpty(QY010101_begin) && !Strings.isNullOrEmpty(QY010101_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY010101" + "_" + regionYear).gte(QY010101_begin).lte(QY010101_end));
            } else if (!Strings.isNullOrEmpty(QY010101_begin)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY010101" + "_" + regionYear).gte(QY010101_begin));
            } else if (!Strings.isNullOrEmpty(QY010101_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY010101" + "_" + regionYear).lte(QY010101_end));
            }

            // 一般公共预算收入
            String QY020102_begin = request.getString("QY020102_begin");
            String QY020102_end = request.getString("QY020102_end");
            if (!Strings.isNullOrEmpty(QY020102_begin) && !Strings.isNullOrEmpty(QY020102_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020102" + "_" + regionYear).gte(QY020102_begin).lte(QY020102_end));
            } else if (!Strings.isNullOrEmpty(QY020102_begin)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020102" + "_" + regionYear).gte(QY020102_begin));
            } else if (!Strings.isNullOrEmpty(QY020102_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020102" + "_" + regionYear).lte(QY020102_end));
            }

            // 一般公共预算支出
            String QY020105_begin = request.getString("QY020105_begin");
            String QY020105_end = request.getString("QY020105_end");
            if (!Strings.isNullOrEmpty(QY020105_begin) && !Strings.isNullOrEmpty(QY020105_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020105" + "_" + regionYear).gte(QY020105_begin).lte(QY020105_end));
            } else if (!Strings.isNullOrEmpty(QY020105_begin)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020105" + "_" + regionYear).gte(QY020105_begin));
            } else if (!Strings.isNullOrEmpty(QY020105_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020105" + "_" + regionYear).lte(QY020105_end));
            }

            // 城镇居民人均可支配收入
            String QY010503_begin = request.getString("QY010503_begin");
            String QY010503_end = request.getString("QY010503_end");
            if (!Strings.isNullOrEmpty(QY010503_begin) && !Strings.isNullOrEmpty(QY010503_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY010503" + "_" + regionYear).gte(QY010503_begin).lte(QY010503_end));
            } else if (!Strings.isNullOrEmpty(QY010503_begin)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY010503" + "_" + regionYear).gte(QY010503_begin));
            } else if (!Strings.isNullOrEmpty(QY010503_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY010503" + "_" + regionYear).lte(QY010503_end));
            }

            // 税收收入
            String QY020103_begin = request.getString("QY020103_begin");
            String QY020103_end = request.getString("QY020103_end");
            if (!Strings.isNullOrEmpty(QY020103_begin) && !Strings.isNullOrEmpty(QY020103_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020103" + "_" + regionYear).gte(QY020103_begin).lte(QY020103_end));
            } else if (!Strings.isNullOrEmpty(QY020103_begin)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020103" + "_" + regionYear).gte(QY020103_begin));
            } else if (!Strings.isNullOrEmpty(QY020103_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY020103" + "_" + regionYear).lte(QY020103_end));
            }

            // 地方政府债务余额
            String QY030201_begin = request.getString("QY030201_begin");
            String QY030201_end = request.getString("QY030201_end");
            if (!Strings.isNullOrEmpty(QY030201_begin) && !Strings.isNullOrEmpty(QY030201_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY030201" + "_" + regionYear).gte(QY030201_begin).lte(QY030201_end));
            } else if (!Strings.isNullOrEmpty(QY030201_begin)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY030201" + "_" + regionYear).gte(QY030201_begin));
            } else if (!Strings.isNullOrEmpty(QY030201_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY030201" + "_" + regionYear).lte(QY030201_end));
            }
            // 广义债务率
            String QY030402_begin = request.getString("QY030402_begin");
            String QY030402_end = request.getString("QY030402_end");
            if (!Strings.isNullOrEmpty(QY030402_begin) && !Strings.isNullOrEmpty(QY030402_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY030402" + "_" + regionYear).gte(QY030402_begin).lte(QY030402_end));
            } else if (!Strings.isNullOrEmpty(QY030402_begin)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY030402" + "_" + regionYear).gte(QY030402_begin));
            } else if (!Strings.isNullOrEmpty(QY030402_end)) {
                mainBuilder.must(QueryBuilders.rangeQuery("QY030402" + "_" + regionYear).lte(QY030402_end));
            }
        }


        // 城投层级
        String region_level = request.getString("region_level");
        if (!Strings.isNullOrEmpty(region_level)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> regionLevels = Splitter.on(",").splitToList(region_level);
            for (String record : regionLevels) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("region_level", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // 城投地位
        String position = request.getString("position");
        if (!Strings.isNullOrEmpty(position)) {
            exersiceBoolQuery = QueryBuilders.boolQuery();
            // 精确查询
            List<String> positions = Splitter.on(",").splitToList(position);
            for (String record : positions) {
                exersiceBoolQuery.should(QueryBuilders.termQuery("position", record));
            }
            if (exersiceBoolQuery.should().size() > 0) {
                mainBuilder.must(exersiceBoolQuery);
            }
        }

        // 非标
        String nonStandard = request.getString("nonStandard");
        if (!Strings.isNullOrEmpty(nonStandard)) {
            mainBuilder.must(QueryBuilders.termQuery("nonStandard.keyword", "FALSE"));
        }

        // 商票逾期
        String accbilloddetail = request.getString("accbilloddetail");
        if (!Strings.isNullOrEmpty(accbilloddetail)) {
            mainBuilder.must(QueryBuilders.termQuery("accbilloddetail.keyword", "FALSE"));
        }

        // QE评级下调
        String qeChange = request.getString("qeChange");
        if (!Strings.isNullOrEmpty(qeChange)) {
            mainBuilder.must(QueryBuilders.termQuery("qeChange.keyword", "FALSE"));
        }

        // 外部评级下调
        String externalChange = request.getString("externalChange");
        if (!Strings.isNullOrEmpty(externalChange)) {
            mainBuilder.must(QueryBuilders.termQuery("externalChange.keyword", "FALSE"));
        }

        // 债券违约
        String dfltinfo = request.getString("dfltinfo");
        if (!Strings.isNullOrEmpty(dfltinfo)) {
            mainBuilder.must(QueryBuilders.termQuery("dfltinfo.keyword", "FALSE"));
        }

        // 纳入失信被执行人
        String tcr0033 = request.getString("tcr0033");
        if (!Strings.isNullOrEmpty(tcr0033)) {
            mainBuilder.must(QueryBuilders.termQuery("tcr0033.keyword", "FALSE"));
        }

        // 非标-区域
        String nonStandardRegion = request.getString("nonStandardRegion");
        if (!Strings.isNullOrEmpty(nonStandardRegion)) {
            mainBuilder.must(QueryBuilders.termQuery("nonStandardRegion.keyword", "FALSE"));
        }

        // 商票逾期-区域
        String accbilloddetailRegion = request.getString("accbilloddetailRegion");
        if (!Strings.isNullOrEmpty(accbilloddetailRegion)) {
            mainBuilder.must(QueryBuilders.termQuery("accbilloddetailRegion.keyword", "FALSE"));
        }

        // 债券违约-区域
        String dfltinoRegion = request.getString("dfltinoRegion");
        if (!Strings.isNullOrEmpty(dfltinoRegion)) {
            mainBuilder.must(QueryBuilders.termQuery("dfltinoRegion.keyword", "FALSE"));
        }

        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("credit_code");

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(mainBuilder);
        queryBuilder.withTrackTotalHits(true);
//        queryBuilder.addAggregation(aggregationBuilder);
        Query query = queryBuilder.build();

        System.out.println(query);
        SearchHits<T> searchHits = elasticsearchTemplate.search(query, t);
        List<T> data = searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
        long recordCount = searchHits.getTotalHits();
        return EsResult.of(data, recordCount);
    }

//    @Override
//    public <T> T sqlFindOne(Class<T> t, String sql) {
//        String queryStr = String.format("{\"query\":\"%s\", \"fetch_size\":1}", sql);
//        return restClientSearch(t, queryStr).stream().findFirst().orElse(null);
//    }
//
//    @Override
//    public <T> List<T> sqlSearch(Class<T> t, String sql) {
//        String queryStr = String.format("{\"query\":\"%s\"}", sql);
//        return restClientSearch(t, queryStr);
//    }

//    /**
//     * 使用restClient 查询数据
//     *
//     * @param t
//     * @param queryStr sql_dsl查询条件
//     * @return
//     */
//    private <T> List<T> restClientSearch(Class<T> t, String queryStr) {
//        try {
//            Request request = new Request("POST", "/_xpack/sql");
//            request.setJsonEntity(queryStr);
//
//            Response response = restClient.performRequest(request);
//            String jsonData = EntityUtils.toString(response.getEntity());
//
//            SQLRestResponse sqlRestResponse = gson.fromJson(jsonData, SQLRestResponse.class);
//            SQLResult<T> sqlResult = ResultUtil.buildFetchSQLResult(sqlRestResponse, t, (SQLResult<T>) null);
//
//            return sqlResult.getDatas();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return new ArrayList<>();
//    }

}



